package utils.global.Interceptor;

import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import utils.global.constant.PassRequest;
import utils.global.jwt.JwtUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.LinkedList;
import java.util.List;


@Slf4j
@Data
public class TokenInterceptorConfig implements HandlerInterceptor {

    protected LinkedList<String> excludePaths = new LinkedList<>();

    public TokenInterceptorConfig() {
        excludePaths.add("/tokencallback");
    }

    @Autowired
    JwtUtils jwtUtils;

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        /* 判断是否为 控制 方法 */
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        /* 判断是否为 公共开放 资源 */
        if (((HandlerMethod) handler).getMethod().isAnnotationPresent(PassRequest.class)) {
            if (((HandlerMethod) handler).getMethod().getAnnotation(PassRequest.class).value()) {
                return true;
            }
        }

        /* 判断是否携带 token */
        String token = request.getHeader("accessToken");
        if (token == null || "".equals(token)) {
            response.sendRedirect("/tokencallback");
            return true;
        }

        /* 校验 token 信息 */
        DecodedJWT verify = jwtUtils.verify(token);

        /* 检验失败 跳转 回调接口 */
        if (verify == null) {
            response.sendRedirect("/tokencallback");
            return true;
        } else {

            /* 版本不一致 跳转 回调 */
            if (verify.getClaim("version").asString().equals(jwtUtils.getVersion())) {
                response.sendRedirect("/tokencallback");
                return true;
            }
        }
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

    public void addexcludePaths(List<String> paths) {
        this.excludePaths.addAll(paths);
    }

    public TokenInterceptorConfig addexcludePath(String path) {
        this.excludePaths.add(path);
        return this;
    }
}
